﻿// -------------------------------------------------------------------------
//    @FileName         :    NFCityNpcMgr.cpp
//    @Author           :    Gao.Yi
//    @Date             :    2025-09-29
//    @Email			:    445267987@qq.com
//    @Module           :    NFCityNpcMgr
//    @Desc             :
//
// -------------------------------------------------------------------------

#include "NFCityNpcMgr.h"
#include "NFCityMapInst.h"
#include "NFCityNpc.h"
#include "NFCityNpcUtil.h"
#include "DescStore/FunctionNpcDesc.h"
#include "DescStore/NpcSpawnDesc.h"

NFCityNpcMgr::NFCityNpcMgr()
{
    if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFCityNpcMgr::~NFCityNpcMgr()
{
}

int NFCityNpcMgr::CreateInit()
{
    return 0;
}

int NFCityNpcMgr::ResumeInit()
{
    return 0;
}

int NFCityNpcMgr::Init(NFCityMapInst* pMapInst)
{
    CHECK_NULL(0, pMapInst);
    int iRetCode = 0;

    m_iMapInstID = pMapInst->GetGlobalId();
    m_iMapDescID = pMapInst->GetMapDescId();

    iRetCode = InitStaticNpc();
    CHECK_ERR(0, iRetCode, "Init static npc failed!");

    iRetCode = InitDynamicNpc();
    CHECK_ERR(0, iRetCode, "Init dynamic npc failed!");

    return 0;
}

NFCityNpcSpawnData* NFCityNpcMgr::FindSpawnData(int iId)
{
    auto iter = m_aoSpawnData.find(iId);
    if (iter != m_aoSpawnData.end())
    {
        return &iter->second;
    }
    return nullptr;
}

int NFCityNpcMgr::OnRemoveNpc(NFCityNpc* pNpc)
{
    CHECK_NULL(0, pNpc);

    auto pSpawnData = FindSpawnData(pNpc->GetSpawnId());
    if (pSpawnData)
    {
        pSpawnData->OnRemoveNpc(pNpc->GetGlobalId(), pNpc->GetLocationId(), pNpc->GetNpcID());
    }
    return 0;
}

int NFCityNpcMgr::Tick()
{
    for (auto iter = m_aoSpawnData.begin(); iter != m_aoSpawnData.end(); ++iter)
    {
        iter->second.Tick();
    }
    return 0;
}

int NFCityNpcMgr::InitStaticNpc()
{
    for (int i = 0; i < FunctionNpcDesc::Instance()->GetResNum(); ++i)
    {
        auto pDesc = FunctionNpcDesc::Instance()->GetDescByIndex(i);
        if (!pDesc)
            continue;

        if (pDesc->is_static && m_iMapDescID == pDesc->map_id)
        {
            Proto_Vector3 oPos;
            oPos.x = pDesc->x_axis;
            oPos.y = pDesc->y_axis;
            oPos.z = pDesc->z_axis;

            NFCityNpc* pNpc = NFCityNpcUtil::CreateNpc(m_iMapInstID, pDesc->id, oPos, 0, 0);
            CHECK_NULL_WF(0, pNpc, "Create static npc failed, npc_id: {}", pDesc->id);
        }
    }

    return 0;
}

int NFCityNpcMgr::InitDynamicNpc()
{
    int iRetCode = 0;
    for (int i = 0; i < NpcSpawnDesc::Instance()->GetResNum(); ++i)
    {
        auto pstNpcSpawnDesc = NpcSpawnDesc::Instance()->GetDescByIndex(i);
        if (!pstNpcSpawnDesc)
            continue;

        if (pstNpcSpawnDesc->is_valid && pstNpcSpawnDesc->map_id == m_iMapDescID)
        {
            NFCityNpcSpawnData* pNpcSpawnData = AddSpawnData(pstNpcSpawnDesc->id);
            CHECK_NULL_WF(0, pNpcSpawnData, "Add spawn data failed, spawn_id: {}", pstNpcSpawnDesc->id);

            iRetCode = pNpcSpawnData->Init(m_iMapInstID, pstNpcSpawnDesc->id);
            CHECK_ERR(0, iRetCode, "Spawn data init failed");
        }
    }

    return 0;
}

NFCityNpcSpawnData* NFCityNpcMgr::AddSpawnData(int iId)
{
    if (m_aoSpawnData.full())
    {
        LOG_ERR(0, -1, "spawn data full, max num: {}", MAX_SPAWN_DATA_PER_MAP);
        return nullptr;
    }
    return &m_aoSpawnData[iId];
}
